/**
 * PeriodicTable reads a text file containing elements from the periodic table.  The data from the file is
 * contained in an array of the object Element.  PeriodicTable asks the user for a chemical formula.  Using
 * regular expressions the total atomic weight of the formula is calculated and output.  The user must enter
 * the chemical formula using proper notation (ie FeH2O).
 * 
 * @author (Jeff Thomas) 
 * @version (11.05.2007)
 * @course (CSC 131 - 1)
 * @assignment (PROG6)
 */

import java.io.*;
import java.util.*;
import java.util.regex.*;

public class PeriodicTable {
    public static void main(String[] args) throws FileNotFoundException {
        int ELEMENTS = 103;
        // Windows
        File filePath = new File("c:/ptable.txt");
        // Linux
        //File filePath = new File("/home/ptable.txt");
        Element[] elements = new Element[ELEMENTS];
        Scanner input = new Scanner(filePath);
        // Ignore the first line
        String s = input.nextLine();
        // Read data from the file
        for (int i = 0; i < ELEMENTS; i++) {
            s = input.nextLine();
            s = s.replaceAll("\t\t", "\t");
            String[] fields = s.split("\t");
            String name = fields[0];
            int number = Integer.parseInt(fields[1]);
            String symbol = fields[2];
            double weight = Double.parseDouble(fields[3]);
            // Create new Element
            Element e = new Element(name, symbol, number, weight);
            elements[i] = e;
        }
        String formula = new String();
        int occurance = 0;
        double totalWeight = 0.0;
        boolean done = false;
        Scanner kybrd = new Scanner(System.in);
        do {
            System.out.print("Please enter your molecular equation (ie. H2O): ");
            formula = kybrd.next();
            if (formula.equals("QUIT") || formula.equals("quit"))
                // quit on user input
                done = true;
            else {
                // setup our regular expression, divide and conquer.
                Pattern pattern = Pattern.compile("[A-Z][a-z]*[1-9]*");
                Matcher matcher = pattern.matcher(formula);
                String temp = "";
                String elem = "";
                int occur = 0;
                double weight = 0.0;
                while (matcher.find()) {
                    temp = matcher.group();
                    // seperates the element from the number
                    Pattern p = Pattern.compile("[A-Z][a-z]*");
                    Matcher m = p.matcher(temp);
                    while (m.find()) {
                        elem = m.group();
                    }
                    // determine how many times each element occurs in the formula
                    temp = temp.substring(temp.length() - 1);
                        if (isNumeric(temp))
                            occur = Integer.parseInt(temp);
                        else
                            occur = 1;
                    for (int j = 0; j < elements.length; j++) {
                    if (elements[j].getSymbol().equals(elem))
                        totalWeight = totalWeight + (elements[j].getWeight() * occur);
                    }
                }
                System.out.println("Total atomic weight is " + totalWeight);
                System.out.println();
                totalWeight = 0.0; //reset total weight
            }
        } while (!done);
    }
    
    // isNumeric determines if a string is a number by testing if it throws an exception
    private static boolean isNumeric(String str){
        try {
            Integer.parseInt(str);
            return true;
        } catch (NumberFormatException nfe){
            return false;
        }
    }
}